package io.xxx.xbutler.core.select.receiver;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.xxx.xbutler.client.StoreClient;
import io.xxx.xbutler.domain.Contact;
import io.xxx.xbutler.domain.Room;
import io.xxx.xbutler.domain.SelectMode;
import io.xxx.xbutler.domain.task.Receiver;
import io.xxx.xbutler.domain.task.ReceiverType;
import io.xxx.xbutler.domain.task.Task;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;

import java.util.List;

@Slf4j
@Component
public class StoreLabelReceiverSelector extends AbstractReceiverSelector {

    @Resource
    private StoreClient storeClient;

    @Override
    public Flux<Receiver> select(Task task) {
        ReceiverType receiverType = task.getReceiverType();
        JSONObject content = JSON.parseObject(task.getSelectContent());
        Long labelItemId = content.getLong("labelItemId");

        return Flux.create(emitter -> {
            try {
                long nextId = 0L;
                do {
                    @SuppressWarnings("BlockingMethodInNonBlockingContext")
                    Pair<List<Long>, Long> pair = storeClient.getStoreIds(labelItemId, nextId);
                    List<Long> storeIds = pair.getFirst();
                    nextId = pair.getSecond();

                    emit(receiverType, storeIds, emitter);
                } while (nextId != 0);
            } catch (Exception e) {
                log.error("查询符合标签的门店列表异常[taskId:{}, labelItemId:{}]", task.getId(), labelItemId, e);
                emitter.error(e);
            }
        });
    }

    private void emit(ReceiverType receiverType, List<Long> storeIds, FluxSink<Receiver> emitter) {
        switch (receiverType) {
            case CONTACT: {
                List<Contact> contacts = contactMapper.selectListByStoreIds(storeIds);
                for (Contact contact : contacts) {
                    Receiver receiver = buildReceiver(contact);
                    emitter.next(receiver);
                }
            }
            case ROOM: {
                List<Room> rooms = roomMapper.selectListByStoreIds(storeIds);
                for (Room room : rooms) {
                    Receiver receiver = buildReceiver(room);
                    emitter.next(receiver);
                }
            }
        }
    }

    @Override
    public boolean supports(SelectMode selectMode) {
        return selectMode == SelectMode.STORE_LABEL;
    }
}
